package cn.xinfei.xdecision.engine.runner.datax;

import cn.xinfei.xdecision.common.model.datax.exception.XDecisionDataExceptionType;
import cn.xinfei.xdecision.common.utils.util.JsonUtil;
import cn.xinfei.xdecision.constant.EngineResultEnum;
import cn.xinfei.xdecision.data.CreditDataApiInterface;
import cn.xinfei.xdecision.data.RiskDataApiInterface;
import cn.xinfei.xdecision.engine.runner.context.PipelineContextHolder;
import cn.xinfei.xdecision.engine.runner.context.XDecisionContext;
import cn.xinfei.xdecision.engine.runner.executor.model.InterVariableConstant;
import cn.xinfei.xdecision.engine.runner.executor.model.StateTransmitModel;
import cn.xinfei.xdecision.engine.runner.metadata.PrometheusTagsConstants;
import cn.xinfei.xdecision.engine.runner.service.DecisionResultService;
import cn.xinfei.xdecision.model.CreditVarRequest;
import cn.xinfei.xdecision.model.CreditVarResponse;
import cn.xinfei.xdecision.model.VariableApiRequest;
import cn.xinfei.xdecision.nacos.NacosSwitchProperties;
import com.alibaba.fastjson.JSONObject;
import com.dianping.cat.Cat;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.micrometer.core.instrument.MeterRegistry;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;

@Data
@Slf4j
@Service
public class DataCreditApplyHandler extends RiskDataApiAdapter<VariableApiRequest, Boolean> {

    @Autowired
    private MeterRegistry meterRegistry;

    @Autowired
    private RiskDataApiInterface riskDataApiInterface;

    @Autowired
    private CreditDataApiInterface creditCollect;

    @Autowired
    private DecisionResultService decisionResultService;

    @Override
    protected Boolean exec(VariableApiRequest variableApiRequest) throws Exception {

        try {
            ConcurrentMap<String, Object> contextValue = PipelineContextHolder.getContextValue();
            String decisionId = PipelineContextHolder.getDecisionId();
            CreditVarRequest request = new CreditVarRequest();
            request.setRequestId(decisionId);
            Set<String> varCodes = variableApiRequest.getVarCodes();
            request.setVarCodes(varCodes);
//            request.setInputParams(JSONObject.parseObject(JsonUtil.toJson(contextValue)));

            ObjectMapper mapper = new ObjectMapper();
            String jsonString = mapper.writeValueAsString(contextValue);
            JSONObject obj = mapper.readValue(jsonString, JSONObject.class);
            request.setInputParams(obj);

            CreditVarResponse dataApiResponse = creditCollect.creditCollect(request);
            log.info("DataCreditApplyHandler.exec response={}",JsonUtil.toJson(dataApiResponse));

            if (null != dataApiResponse) {
                String code = dataApiResponse.getCode();
                if (String.valueOf(XDecisionDataExceptionType.SUCCESS.code).equals(code)) {
                    if (NacosSwitchProperties.getNacosSwitchProperties().isDebugLog()) {
                        log.info("人行变量申请接口成功，response={}", JsonUtil.toJson(dataApiResponse));
                    }
                    Object data = dataApiResponse.getData();
                    if(data!=null){
                        Map fieldInfo = JSONObject.parseObject(data.toString(), Map.class);
                        Object status = fieldInfo.get("status");
                        if(status!=null){
                            Object credit_channel = fieldInfo.get(InterVariableConstant.CREDIT_CHANNEL);
                            PipelineContextHolder.putInContext("credit", InterVariableConstant.CREDIT_CHANNEL,credit_channel);
                            String s = status.toString();
                            StateTransmitModel stateContext = XDecisionContext.getContext().getStateContext();
                            if("1".equals(s)){
                                if (NacosSwitchProperties.getNacosSwitchProperties().isDebugLog()) {
                                    log.info("人行变量申请成功");
                                }
                                stateContext.setEngineResultEnum(EngineResultEnum.CREDIT_PENDING_FETCH);
                                return true;
                            }

                            if("-1".equals(s)){
                                stateContext.setEngineResultEnum(EngineResultEnum.REVIEW);//阻塞住不再重试
                                if (NacosSwitchProperties.getNacosSwitchProperties().isDebugLog()) {
                                    log.info("人行不需要上报");
                                }
                                return false;
                            }
                            stateContext.setEngineResultEnum(EngineResultEnum.CREDIT_PENDING_APPLY);
                            if (NacosSwitchProperties.getNacosSwitchProperties().isDebugLog()) {
                                log.error("人行变量申请失败，重新申请");
                            }
                        }
                    }
                }
                log.info("DataCreditApplyHandler.exec request={}",JsonUtil.toJson(request));
                meterRegistry.counter("xdecision_credit_apply_total", PrometheusTagsConstants.XDATA_API_TOTAL_TAGS.and("code", code)).increment();
            } else {
                meterRegistry.counter("xdecision_credit_apply_total", PrometheusTagsConstants.XDATA_API_TOTAL_TAGS.and("code", "null")).increment();
            }
        } catch (Exception e) {
            log.error("DataCreditApplyHandler exception. error={},variableApiRequest={}", e.getMessage(), JsonUtil.toJson(variableApiRequest), e);
            XDecisionContext.getContext().getStateContext().setEngineResultEnum(EngineResultEnum.CREDIT_PENDING_APPLY);
            Cat.logError(e);
            meterRegistry.counter("xdecision_credit_apply_total", PrometheusTagsConstants.XDATA_API_TOTAL_TAGS.and("code", "exception")).increment();
            throw e;
        }
        return false;
    }
}
